package com.x.bff.app.factory.cms;

import com.x.bff.app.model.vo.cms.*;
import com.x.bff.app.model.vo.customer.CustomerSimpleVO;
import com.x.bff.app.model.vo.customer.CustomerStatVO;
import com.x.core.utils.BeanUtil;
import com.x.provider.api.customer.model.dto.customer.CustomerSimpleDTO;
import com.x.provider.api.general.model.dto.cms.ContentDTO;
import com.x.provider.api.general.model.dto.cms.ItemToggleRelationDTO;
import com.x.provider.api.oss.service.OssRpcService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

@Service
public class ContentFactoryImpl implements ContentFactory {

    private final OssRpcService ossRpcService;

    public ContentFactoryImpl(OssRpcService ossRpcService){
        this.ossRpcService = ossRpcService;
    }

    @Override
    public List<ContentVO> prepare(List<ContentDTO> src) {
        List<ContentVO> result = new ArrayList<>(src.size());
        src.stream().forEach(item ->{
            ContentVO contentVO = copy(item);
            result.add(contentVO);
        });
        prepareUrl(result);
        return result;
    }

    private ContentVO copy(ContentDTO item) {
        ContentVO contentVO = BeanUtil.prepare(item, ContentVO.class);
        if (!CollectionUtils.isEmpty(item.getContentMediaList())){
            contentVO.setContentMediaList(new ArrayList<>(item.getContentMediaList().size()));
            item.getContentMediaList().stream().forEach(opt -> {
                ContentMediaVO contentMediaVO = BeanUtil.prepare(opt, ContentMediaVO.class);
                if (opt.getContentMediaPicture() != null){
                    contentMediaVO.setContentMediaPicture(BeanUtil.prepare(opt.getContentMediaPicture(), ContentMediaPictureVO.class));
                }
                if (opt.getContentMediaVideo() != null){
                    contentMediaVO.setContentMediaVideo(BeanUtil.prepare(opt.getContentMediaVideo(), ContentMediaVideoVO.class));
                }
                contentVO.getContentMediaList().add(contentMediaVO);
            });
        }
        return contentVO;
    }

    @Override
    public ContentVO prepare(ContentDTO contentDTO) {
        ContentVO result = copy(contentDTO);
        Set<String> pictureFileIds = new HashSet<>();
        Set<String> videoFileIds = new HashSet<>();
        listFileId(pictureFileIds, videoFileIds, result);
        Map<String, String> urlMap = new HashMap<>();
        if (!pictureFileIds.isEmpty()){
            urlMap.putAll(ossRpcService.listObjectBrowseUrl(new ArrayList<>(pictureFileIds)).getData());
        }
        prepareUrl(urlMap, result);
        return result;
    }

    @Override
    public List<CustomerSimpleVO> prepareCustomerSimple(List<CustomerSimpleDTO> src) {
        if (CollectionUtils.isEmpty(src)){
            return new ArrayList<>();
        }
        List<CustomerSimpleVO> result = new ArrayList<>(src.size());
        src.stream().forEach(item ->{
            CustomerSimpleVO customerSimpleVO = BeanUtil.prepare(item, CustomerSimpleVO.class);
            customerSimpleVO.setStatistic(BeanUtil.prepare(item.getStatistic(), CustomerStatVO.class));
            result.add(customerSimpleVO);
        });
        return result;
    }

    public void prepareUrl(List<ContentVO> src){
        Set<String> pictureFileIds = new HashSet<>(src.size());
        Set<String> videoFileIds = new HashSet<>(src.size());
        listFileId(src, pictureFileIds, videoFileIds);
        Map<String, String> urlMap = new HashMap<>(src.size() * 2);
        if (!pictureFileIds.isEmpty()) {
            urlMap.putAll(ossRpcService.listObjectBrowseUrl(new ArrayList<>(pictureFileIds)).getData());
        }
        prepareUrl(src, urlMap);
    }

    private void listFileId(List<ContentVO> src, Set<String> pictureFileIds, Set<String> videoFileIds) {
        src.stream().forEach(item ->{
            listFileId(pictureFileIds, videoFileIds, item);
        });
    }

    private void listFileId(Set<String> pictureFileIds, Set<String> videoFileIds, ContentVO item) {
        if (!StringUtils.isEmpty(item.getCoverFileId())){
            pictureFileIds.add(item.getCoverFileId());
        }
        if (!CollectionUtils.isEmpty(item.getContentMediaList())){
            item.getContentMediaList().stream().forEach(opt ->{
                if (opt.getContentMediaPicture() != null){
                    pictureFileIds.add(opt.getContentMediaPicture().getFileId());
                }
                if (opt.getContentMediaVideo() != null){
                    videoFileIds.add(opt.getContentMediaVideo().getFileId());
                }
            });
        }
    }

    private void prepareUrl(List<ContentVO> src, Map<String, String> urlMap) {
        src.stream().forEach(item ->{
            prepareUrl(urlMap, item);
        });
    }

    private void prepareUrl(Map<String, String> urlMap, ContentVO item) {
        if (!StringUtils.isEmpty(item.getCoverFileId())){
            item.setCoverFileIdUrl(urlMap.get(item.getCoverFileId()));
        }
        if (!CollectionUtils.isEmpty(item.getContentMediaList())){
            item.getContentMediaList().stream().forEach(opt ->{
                if (opt.getContentMediaPicture() != null){
                    opt.getContentMediaPicture().setFileIdUrl(urlMap.get(opt.getContentMediaPicture().getFileId()));
                }
                if (opt.getContentMediaVideo() != null){
                    opt.getContentMediaVideo().setFileIdUrl(urlMap.get(opt.getContentMediaVideo().getFileId()));
                }
            });
        }
    }



    public static ItemToggleBothRelationVO prepareFromRelation(ItemToggleBothRelationVO dest, ItemToggleRelationDTO src){
        if (dest == null){
            dest = new ItemToggleBothRelationVO();
        }
        if (src == null){
            return dest;
        }
        dest.setFromRelation(src.getRelation());
        dest.setBothRelation(src.getBothRelation());
        return dest;
    }

    public static ItemToggleBothRelationVO prepareToRelation(ItemToggleBothRelationVO dest, ItemToggleRelationDTO src){
        if (dest == null){
            dest = new ItemToggleBothRelationVO();
        }
        if (src == null){
            return dest;
        }
        dest.setToRelation(src.getRelation());
        dest.setBothRelation(src.getBothRelation());
        return dest;
    }

    public ItemToggleBothRelationVO prepareBothRelation(ItemToggleRelationDTO fromRelation, ItemToggleRelationDTO toRelation){
        ItemToggleBothRelationVO result = new ItemToggleBothRelationVO();
        prepareFromRelation(result, fromRelation);
        prepareToRelation(result, toRelation);
        return result;
    }
}
